package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.dto.BaseInfoDto;
import com.itheima.dto.ProfileDto;
import com.itheima.dto.SysUserRoleDto;
import com.itheima.dto.YddCateDto;
import com.itheima.dto.*;
import com.itheima.entity.*;
import com.itheima.service.*;
import com.itheima.untils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private YddCateService yddCateService;

    @Autowired
    private YddTagService yddTagService;

    @Autowired
    private YddLinkService yddLinkService;

    @Autowired
    private YddAdvimgService yddAdvimgService;

    @Autowired
    private YddArticleService yddArticleService;

    @Autowired
    private YddUserDataService yddUserDataService;

    @Autowired
    private YddAdvposService yddAdvposService;

    @Autowired
    private YddUserService yddUserService;

    /**
     * 获取系统配置
     *
     * @return
     */
    public Map<String, String> getConfig() {
        //根据tab_value=system取到所有system的数据
        LambdaQueryWrapper<SysConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysConfig::getTabValue, "system");
        List<SysConfig> sysConfigList = sysConfigService.list(queryWrapper);

        //封装页面需要的数据
        Map<String, String> map = new HashMap<>();
        sysConfigList.stream().map((item) -> {
            map.put(item.getAttrKey(), item.getAttrValue());
            return item;
        }).collect(Collectors.toList());

        return map;
    }

    /**
     * 获取用户资料
     *
     * @param id
     * @return
     */
    @Override
    public ProfileDto getProfile(String id) {
        //创建profileDto封装用户资料
        ProfileDto profileDto = new ProfileDto();

        //userInfo
        //创建sysUserRoleDto补充角色id和角色名称信息
        SysUserRoleDto sysUserRoleDto = new SysUserRoleDto();
        //获取用户资料
        SysUser sysUser = sysUserService.getById(id);
        //处理角色id
        String[] roleId = sysUser.getRoleId().replace("[", "")
                .replace("]", "")
                .replace("\"", "")
                .split(", ");
        //获取角色名称
        List<String> nameList = Arrays.stream(roleId).map((item) -> {
            SysRole sysRole = sysRoleService.getById(item);
            String name = sysRole.getName();
            return name;
        }).collect(Collectors.toList());
        //封装sysUserRoleDto
        sysUserRoleDto.setRole_id(roleId);
        sysUserRoleDto.setRolename(nameList);
        //数据copy
        BeanUtils.copyProperties(sysUser, sysUserRoleDto);

        //menuList
        //根据roleId获取到menuId
        LambdaQueryWrapper<SysRoleMenu> sysRoleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleMenuLambdaQueryWrapper.in(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuService.list(sysRoleMenuLambdaQueryWrapper);
        List<String> menuIdList = sysRoleMenuList.stream().map(item -> {
            return item.getMenuId();
        }).collect(Collectors.toList());
        //根据menuId获取用户菜单权限
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysMenuLambdaQueryWrapper.in(SysMenu::getId, menuIdList);
        sysMenuLambdaQueryWrapper.orderByAsc(SysMenu::getSort);
        sysMenuLambdaQueryWrapper.like(SysMenu::getPath, "/");
        sysMenuLambdaQueryWrapper.eq(SysMenu::getIsShow, 1);
        List<SysMenu> sysMenuList = sysMenuService.list(sysMenuLambdaQueryWrapper);

        //dictsList
        //获取type分类的名称
        LambdaQueryWrapper<SysDict> sysDictLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDictLambdaQueryWrapper.select(SysDict::getType).groupBy(SysDict::getType);
        List<Object> typeList = sysDictService.listObjs(sysDictLambdaQueryWrapper);
        log.info("typeList======={}", typeList);
        //创建map存放typeList下的属性
        Map<String, Map<String,String>> sysDictMap = new HashMap<>();
        for (Object item : typeList) {
            //获取每个typeList下的数据
            LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysDict::getType, item);
            List<SysDict> itemList = sysDictService.list(queryWrapper);
            //key:value数据值  value:label标签名
            Map<String, String> map = new HashMap<>();
            for (SysDict sysDict : itemList) {
                map.put(sysDict.getValue(), sysDict.getLabel());
            }
            //为整个dictsList赋值
            sysDictMap.put((String) item, map);
        }

        //btnList
        //用户按钮权限
        String[] btnList = {"*"};

        //set profileDto
        profileDto.setUserInfo(sysUserRoleDto);
        profileDto.setMenuList(sysMenuList);
        profileDto.setDictsList(sysDictMap);
        profileDto.setBtnList(btnList);
        return profileDto;
    }

    /**
     * 主页统计信息
     *
     * @return
     */
    @Override
    public BaseInfoDto getBaseInfo() {
        //创建baseInfoDto封装主页信息
        BaseInfoDto baseInfoDto = new BaseInfoDto();

        //admin_num
        //统计管理员总数
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.select(SysUser::getId);
        int adminNum = sysUserService.count(sysUserLambdaQueryWrapper);

        //advimg_num
        //统计广告图总数
        LambdaQueryWrapper<YddAdvimg> yddAdvimgLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddAdvimgLambdaQueryWrapper.select(YddAdvimg::getId);
        int advimgNum = yddAdvimgService.count(yddAdvimgLambdaQueryWrapper);

        //advpos_num
        //广告位总数
        LambdaQueryWrapper<YddAdvpos> yddAdvposLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddAdvposLambdaQueryWrapper.select(YddAdvpos::getId);
        int advposNum = yddAdvposService.count(yddAdvposLambdaQueryWrapper);

        //all_cate
        //所有分类数据
        List<YddCate> yddCateList = yddCateService.list();
        List<YddCateDto> yddCateDto = yddCateList.stream().map(item -> {
            YddCateDto cateDto = new YddCateDto();
            BeanUtils.copyProperties(item, cateDto);
            Integer id = item.getId();
            LambdaQueryWrapper<YddArticle> yddArticleLambdaQueryWrapper = new LambdaQueryWrapper<>();
            yddArticleLambdaQueryWrapper.eq(YddArticle::getCateid, id);
            int num = yddArticleService.count(yddArticleLambdaQueryWrapper);
            cateDto.setNum(num);
            return cateDto;
        }).collect(Collectors.toList());

        //文章总数
        //article_num
        LambdaQueryWrapper<YddArticle> yddArticleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddArticleLambdaQueryWrapper.select(YddArticle::getId);
        int articleNum = yddArticleService.count(yddArticleLambdaQueryWrapper);

        //分类总数
        //cate_num
        LambdaQueryWrapper<YddCate> yddCateLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddCateLambdaQueryWrapper.select(YddCate::getId);
        int cateNum = yddCateService.count(yddCateLambdaQueryWrapper);

        //hot_article
        //热门文章数据
        Page<YddArticle> yddArticlePage = new Page<>(1, 7);
        LambdaQueryWrapper<YddArticle> yddArticleQueryWrapper = new LambdaQueryWrapper<>();
        yddArticleQueryWrapper.orderByDesc(YddArticle::getClick);
        yddArticleService.page(yddArticlePage, yddArticleQueryWrapper);
        List<YddArticle> hotArticleList = yddArticlePage.getRecords();

        //new_user
        //最新用户数据
        Page<YddUser> yddUserPage = new Page<>(1, 7);
        LambdaQueryWrapper<YddUser> yddUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddUserLambdaQueryWrapper.orderByDesc(YddUser::getId);
        yddUserService.page(yddUserPage, yddUserLambdaQueryWrapper);
        List<YddUser> newUserList = yddUserPage.getRecords();

        //tag_num
        //标签总数
        LambdaQueryWrapper<YddTag> yddTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddTagLambdaQueryWrapper.select(YddTag::getId);
        int tagNum = yddTagService.count(yddTagLambdaQueryWrapper);

        //用户总数 男用户数量 女用户数量
        //totalUser
        //用户总数
        LambdaQueryWrapper<YddUser> yddUserLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        yddUserLambdaQueryWrapper1.select(YddUser::getId);
        int total = yddUserService.count(yddUserLambdaQueryWrapper1);
        //男用户数量
        LambdaQueryWrapper<YddUser> yddUserLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        yddUserLambdaQueryWrapper2.eq(YddUser::getSex, 0);
        int user_man = yddUserService.count(yddUserLambdaQueryWrapper2);
        //女用户数量
        LambdaQueryWrapper<YddUser> yddUserLambdaQueryWrapper3 = new LambdaQueryWrapper<>();
        yddUserLambdaQueryWrapper3.eq(YddUser::getSex, 1);
        int user_woman = yddUserService.count(yddUserLambdaQueryWrapper3);
        //处理数据
        Map<String, Integer> map = new HashMap<>();
        map.put("total", total);
        map.put("user_man", user_man);
        map.put("user_woman", user_woman);

        //封装
        baseInfoDto.setAdmin_num(adminNum);
        baseInfoDto.setAdvimg_num(advimgNum);
        baseInfoDto.setAdvpos_num(advposNum);
        baseInfoDto.setAll_cate(yddCateDto);
        baseInfoDto.setArticle_num(articleNum);
        baseInfoDto.setCate_num(cateNum);
        baseInfoDto.setHot_article(hotArticleList);
        baseInfoDto.setNew_user(newUserList);
        baseInfoDto.setTag_num(tagNum);
        baseInfoDto.setUser(map);
        return baseInfoDto;
    }

    /**
     * 前台首页和全局数据
     * @return
     */
    @Override
    public FrontIndexDto index() {
        LambdaQueryWrapper<YddCate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YddCate::getDefaultData,1);
        List<YddCate> cateList = yddCateService.list(queryWrapper);

        LambdaQueryWrapper<YddLink> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(YddLink::getDefaultData,1);
        List<YddLink> linkList = yddLinkService.list(queryWrapper1);

        LambdaQueryWrapper<YddTag> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(YddTag::getDefaultData,1);
        List<YddTag> tagList = yddTagService.list(queryWrapper2);

        LambdaQueryWrapper<YddAdvimg> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.eq(YddAdvimg::getAdvimgpos,13);
        List<YddAdvimg> list1 = yddAdvimgService.list(queryWrapper3);

        LambdaQueryWrapper<YddAdvimg> queryWrapper4 = new LambdaQueryWrapper<>();
        queryWrapper4.eq(YddAdvimg::getAdvimgpos,14);
        List<YddAdvimg> list2 = yddAdvimgService.list(queryWrapper4);

        LambdaQueryWrapper<YddAdvimg> queryWrapper5 = new LambdaQueryWrapper<>();
        queryWrapper5.eq(YddAdvimg::getAdvimgpos,15);
        List<YddAdvimg> list3 = yddAdvimgService.list(queryWrapper5);



        LambdaQueryWrapper<SysConfig> sysConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysConfigLambdaQueryWrapper.eq(SysConfig::getDelFlag,0).orderByDesc(SysConfig::getSortNum);
        List<SysConfig> sysConfigList = sysConfigService.list(sysConfigLambdaQueryWrapper);

        //封装第一个list的数据
        ListDto listDto1 = new ListDto();
        listDto1.setKey("base");
        listDto1.setName("基础设置");

        LambdaQueryWrapper<SysConfig> qw = new LambdaQueryWrapper<>();
        ChildrenDto childrenDto1 = new ChildrenDto();
        qw.eq(SysConfig::getGroupValue,"站点配置");
        List<SysConfig> children1 = sysConfigService.list(qw);
        childrenDto1.setData(children1);
        childrenDto1.setName("站点配置");

        LambdaQueryWrapper<SysConfig> qw1 = new LambdaQueryWrapper<>();
        ChildrenDto childrenDto2 = new ChildrenDto();
        qw1.eq(SysConfig::getGroupValue,"底部信息");
        List<SysConfig> children2 = sysConfigService.list(qw1);
        childrenDto2.setData(children2);
        childrenDto2.setName("底部信息");

        LambdaQueryWrapper<SysConfig> qw2 = new LambdaQueryWrapper<>();
        ChildrenDto childrenDto3 = new ChildrenDto();
        qw2.eq(SysConfig::getGroupValue,"其他配置");
        List<SysConfig> children3 = sysConfigService.list(qw2);
        childrenDto3.setData(children3);
        childrenDto3.setName("其他配置");

        ArrayList<ChildrenDto> childrenDtoList1 = new ArrayList<>();
        childrenDtoList1.add(childrenDto1);
        childrenDtoList1.add(childrenDto2);
        childrenDtoList1.add(childrenDto3);
        listDto1.setChildren(childrenDtoList1);

        //封装第二个list的数据
        ListDto listDto2 = new ListDto();
        listDto2.setKey("custom");
        listDto2.setName("其他设置");

        LambdaQueryWrapper<SysConfig> qw3 = new LambdaQueryWrapper<>();
        ChildrenDto childrenDto4 = new ChildrenDto();
        qw3.eq(SysConfig::getGroupValue,"前台图片");
        List<SysConfig> children4 = sysConfigService.list(qw3);
        childrenDto4.setData(children4);
        childrenDto4.setName("前台图片");

        LambdaQueryWrapper<SysConfig> qw4 = new LambdaQueryWrapper<>();
        ChildrenDto childrenDto5 = new ChildrenDto();
        qw4.eq(SysConfig::getGroupValue,"通知公告");
        List<SysConfig> children5 = sysConfigService.list(qw3);
        childrenDto5.setData(children5);
        childrenDto5.setName("通知公告");

        ArrayList<ChildrenDto> childrenDtoList2 = new ArrayList<>();
        childrenDtoList2.add(childrenDto4);
        childrenDtoList2.add(childrenDto5);
        listDto2.setChildren(childrenDtoList2);

        //封装第三个list的数据
        ListDto listDto3 = new ListDto();
        listDto3.setKey("system");
        listDto3.setName("系统设置");

        LambdaQueryWrapper<SysConfig> qw5 = new LambdaQueryWrapper<>();
        ChildrenDto childrenDto6 = new ChildrenDto();
        qw5.eq(SysConfig::getGroupValue,"管理系统配置");
        List<SysConfig> children6 = sysConfigService.list(qw3);
        childrenDto6.setData(children6);
        childrenDto6.setName("管理系统配置");

        ArrayList<ChildrenDto> childrenDtoList3 = new ArrayList<>();
        childrenDtoList3.add(childrenDto6);
        listDto3.setChildren(childrenDtoList3);


        ArrayList<ListDto> listDtos = new ArrayList<>();
        listDtos.add(listDto1);
        listDtos.add(listDto2);
        listDtos.add(listDto3);

        SysConfigDtoRes sysConfigDtoRes = new SysConfigDtoRes();
        sysConfigDtoRes.setAllData(sysConfigList);
        sysConfigDtoRes.setList(listDtos);

        FrontIndexDto frontIndexDto = new FrontIndexDto();
        frontIndexDto.setAllCate(cateList);
        frontIndexDto.setAllLink(linkList);
        frontIndexDto.setAllTag(tagList);
        frontIndexDto.setBanner(list3);
        frontIndexDto.setShowBanner(list1);
        frontIndexDto.setSideBanner(list2);
        frontIndexDto.setConfig(sysConfigDtoRes);

        return frontIndexDto;
    }

    /**
     * 前台文章列表数据
     * @param page
     * @param limit
     * @param cateid
     * @return
     */
    @Override
    public PageDto getList(String page, String limit, String cateid) {
        int limitInt = Integer.parseInt(limit);
        int pageInt = Integer.parseInt(page);
        Page<YddArticle> articlePage = new Page<>(pageInt,limitInt);
        LambdaQueryWrapper<YddArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YddArticle::getCateid,cateid).orderByDesc(YddArticle::getCreateDate);
        Page<YddArticle> page1 = yddArticleService.page(articlePage, queryWrapper);

        int count = yddArticleService.count();

        PageDto pageDto = new PageDto();

        List<YddArticle> records = page1.getRecords();

        long total = page1.getTotal();

        pageDto.setTotalPages(total);
        pageDto.setData(records);
        pageDto.setCurrentPage((long) pageInt);
        pageDto.setPageSize((long) limitInt);
        pageDto.setCount((long) count);

        return pageDto;
    }

    /**
     * 展示文章的详细信息
     * @param id
     * @param request
     * @return
     */
    @Override
    public HashMap<String, Object> getShow(Integer id, HttpServletRequest request) {
        YddArticle article = yddArticleService.getById(id);
        Integer cateid = article.getCateid();
        YddCate cate = yddCateService.getById(cateid);
        String catename = cate.getCatename();

        String token = request.getHeader("token");
        Claims claims = JwtUtils.parseToken(token);
        Integer userId = (Integer) claims.get("id");

        //封装info数据
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(article,articleDto);
        articleDto.setCatename(catename);

        //设置isLike和isCollect数据
        Boolean likeFlag = false;
        Boolean collectFlag = false;
        LambdaQueryWrapper<YddUserData> queryWrapperUser = new LambdaQueryWrapper<>();
        queryWrapperUser.eq(YddUserData::getArticleId, id).eq(YddUserData::getUserId,userId);
        List<YddUserData> userDataList = yddUserDataService.list(queryWrapperUser);
        if (userDataList.size() != 0) {

            for (YddUserData yddUserData : userDataList) {
                if(yddUserData.getType()==1){
                    collectFlag = true;
                    articleDto.setIsCollect(collectFlag);
                }else if (yddUserData.getType()==2){
                    likeFlag = true;
                    articleDto.setIsLike(likeFlag);
                }
            }

        } else {
            articleDto.setIsLike(likeFlag);
            articleDto.setIsCollect(collectFlag);
        }

        //封装next数据
        LambdaQueryWrapper<YddArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.lt(YddArticle::getId,id);
        List<YddArticle> ltList = yddArticleService.list(queryWrapper);
        String maxTitle = "";
        Integer maxId = null;
        if (ltList.size()>0){
            maxId=ltList.get(ltList.size()-1).getId();
            YddArticle yddArticle = yddArticleService.getById(maxId);
            maxTitle = yddArticle.getTitle();
        }
        HashMap<Object, Object> map = new HashMap<>();
        map.put("id",maxId);
        map.put("title",maxTitle);
        ArrayList<Object> prevList = new ArrayList<>();
        prevList.add(map);

        //封装prev数据
        LambdaQueryWrapper<YddArticle> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(YddArticle::getId,id);
        List<YddArticle> geList = yddArticleService.list(wrapper);
        String minTitle = "";
        Integer minId = null;
        if (geList.size()>0){
            minId=geList.get(geList.size()-1).getId();
            YddArticle yddArticle = yddArticleService.getById(minId);
            minTitle = yddArticle.getTitle();
        }
        HashMap<Object, Object> map1 = new HashMap<>();
        map1.put("id",minId);
        map1.put("title",minTitle);
        ArrayList<Object> nextList = new ArrayList<>();
        nextList.add(map1);

        //封装recommend数据
        Page<YddArticle> yddArticlePage = new Page<>(1,8);
        LambdaQueryWrapper<YddArticle> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(YddArticle::getCateid,cateid).orderByDesc(YddArticle::getCreateDate);
        Page<YddArticle> page = yddArticleService.page(yddArticlePage, lambdaQueryWrapper);
        List<YddArticle> list = page.getRecords();


        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("info",articleDto);
        hashMap.put("next",nextList);
        hashMap.put("prev",prevList);
        hashMap.put("recommend",list);


        return hashMap;
    }
}
